// functional/Closure3.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// {WillNotCompile}

import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.IntSupplier;

public class Closure3 {
//    IntSupplier makeFun(int x) {
//        int i = 0;
//        // Neither x++ nor i++ will work:
//        return () -> x++ + i++;
//    }
    /*
    根据你提供的Closure3.java文件内容，问题出在lambda表达式中引用了两个局部变量x和i，而这两个变量在lambda表达式执行时会被修改（通过x++和i++操作）。
    这违反了Java中lambda表达式的规则：lambda表达式只能引用final或实际上是final的局部变量。
    详细分析
    x是方法参数，虽然它是局部变量，但不能在lambda表达式中被修改。
    i是局部变量，在lambda表达式中通过i++进行修改，这也违反了规则。
    */

  //解决方案
    /*
    1。使用数组来存储可变值
    可以将x和i存储在一个数组中，这样可以间接地修改它们的值。
    */
  IntSupplier makeFun1(int x) {
    int[] i = {0}; // 使用数组来存储可变值
    final int[] xArray = {x}; // 将x也存储在数组中
    return () -> xArray[0]++ + i[0]++;
  }

  /*
  2、使用AtomicInteger
  AtomicInteger是一个线程安全的类，可以用来存储和修改整数值。
  */
  IntSupplier makeFun2(int x) {
    AtomicInteger i = new AtomicInteger(0); // 使用AtomicInteger
    final AtomicInteger xValue = new AtomicInteger(x); // 将x存储在AtomicInteger中
    return () -> xValue.getAndIncrement() + i.getAndIncrement();
  }

  public static void main(String[] args) {
    Closure3 closure3 = new Closure3();

    IntSupplier supplier1 = closure3.makeFun1(5);
    System.out.println(supplier1.getAsInt()); // 输出 5 (5+0)
    System.out.println(supplier1.getAsInt()); // 输出 7 (6+1)
    System.out.println();
    IntSupplier supplier2 = closure3.makeFun2(5);
    System.out.println(supplier2.getAsInt()); // 输出 5 (5+0)
    System.out.println(supplier2.getAsInt()); // 输出 7 (6+1)

  }


}
